package com.jaya.budan.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import androidx.annotation.RequiresApi;

import com.jaya.budan.R;

/**
 * @author: luckly
 * @date: 2020/10/26 2:16 PM
 * @desc: 双向seekbar
 */
public class RangeSeekBarUtil extends View {

    private float lineWidth = 5.0f;
    /**
     * 已选中，黄色背景，可以根据要求自行修改
     */
    private int inRangeColor = Color.parseColor("#FFC901");
    /**
     * 未选中，灰色背景，可以根据要求自行修改
     */
    private int outRangeColor = Color.parseColor("#FF767777");
    /**
     * 中间线的宽度，当前值乘以2（）
     */
    private int currentHeight = 15;
    /**
     * 线的长度
     */
    private int lineLength = 100;
    private int lowerCenterX;
    private int upperCenterX;

    private int bmpWidth;
    private int bmpHeight;

    private Bitmap lowerBmp;
    private Bitmap upperBmp;
    private boolean isLowerMoving = false;
    private boolean isUpperMoving = false;

    private OnRangeChangedListener onRangeChangedListener;

    private int paddingLeft = 50;
    private int paddingRight = 50;
    private int paddingTop = 50;
    private int paddingBottom = 10;

    private int lineHeight;

    private int lineStart = paddingLeft;
    private int lineEnd = lineLength + paddingLeft;

    private float smallValue = 0.0f;
    private float bigValue = 100.0f;

    private float smallRange = smallValue;
    private float bigRange = bigValue;

    private float round;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public RangeSeekBarUtil(Context context) {
        this(context, null);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public RangeSeekBarUtil(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public RangeSeekBarUtil(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }


    public static Bitmap drawableToBitmap(Drawable drawable) {
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
                drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;
    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void init(Context context) {
        lowerBmp = drawableToBitmap(context.getDrawable(R.drawable.seekbarpressure));
        upperBmp = drawableToBitmap(context.getDrawable(R.drawable.seekbarpressure));
        bmpWidth = upperBmp.getWidth();
        bmpHeight = upperBmp.getHeight();
        lineHeight = getHeight() - paddingBottom - lowerBmp.getHeight() / 2;
        lineEnd = getScreenWidth() - paddingLeft - paddingRight + upperBmp.getWidth() / 2;
        lowerCenterX = lineStart;
        upperCenterX = lineEnd;
    }

    private int measureWidth(int measureSpec) {
        int result = 0;

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
            lineLength = getScreenWidth() - paddingLeft - paddingRight - upperBmp.getWidth() / 2;
            lineEnd = getScreenWidth() - paddingLeft - paddingRight + upperBmp.getWidth() / 2;
        } else {
            result = lineLength + paddingLeft + paddingRight + bmpWidth * 2;
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
                lineEnd = result - paddingRight;
            }
        }
        upperCenterX = lineEnd;

        return result;
    }

    private int measureHeight(int measureHeight) {
        int result = 0;

        int specMode = MeasureSpec.getMode(measureHeight);
        int specSize = MeasureSpec.getSize(measureHeight);

        if (specMode == MeasureSpec.EXACTLY) {
            result = bmpHeight * 2;
        } else {
            result = bmpHeight + paddingTop;

            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }

        return result;
    }

    /**
     * 得到屏幕宽度
     *
     * @return
     */
    private int getScreenWidth() {
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        widthMeasureSpec = measureWidth(widthMeasureSpec);
        heightMeasureSpec = measureHeight(heightMeasureSpec);
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        bmpWidth = upperBmp.getWidth();
        bmpHeight = upperBmp.getHeight();
        lineHeight = getHeight() - paddingBottom - lowerBmp.getHeight() / 2;
        lineLength = lineHeight;
        // 画线
        Paint linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setStrokeWidth(lineWidth);
        //圆角
        if (round == 0) {
            round = currentHeight;
        }
        // 绘制处于图片滑块之间线段
        linePaint.setColor(inRangeColor);
        canvas.drawRoundRect(new RectF(lowerCenterX, lineHeight - currentHeight, upperCenterX, lineHeight + currentHeight), round, round, linePaint);
        // 绘制处于图片滑块两端的线段
        linePaint.setColor(outRangeColor);
        canvas.drawRoundRect(new RectF(lineStart, lineHeight - currentHeight, lowerCenterX, lineHeight + currentHeight), round, round, linePaint);
        canvas.drawRoundRect(new RectF(upperCenterX, lineHeight - currentHeight, lineEnd, lineHeight + currentHeight), round, round, linePaint);
        // 画图片滑块
        canvas.drawBitmap(lowerBmp, lowerCenterX - bmpWidth / 2, lineHeight - bmpHeight / 2, null);
        canvas.drawBitmap(lowerBmp, upperCenterX - bmpWidth / 2, lineHeight - bmpHeight / 2, null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        float xPos = event.getX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 如果按下的位置在垂直方向没有与图片接触，则不会滑动滑块
                float yPos = event.getY();
                if (Math.abs(yPos - lineHeight) > bmpHeight / 2) {
                    return false;
                }

                // 表示当前按下的滑块是左边的滑块
                if (Math.abs(xPos - lowerCenterX) < bmpWidth / 2) {
                    isLowerMoving = true;
                }

                // //表示当前按下的滑块是右边的滑块
                if (Math.abs(xPos - upperCenterX) < bmpWidth / 2) {
                    isUpperMoving = true;
                }

                // 单击左边滑块的左边线条时，左边滑块滑动到对应的位置
                if (xPos >= lineStart && xPos <= lowerCenterX - bmpWidth / 2) {
                    lowerCenterX = (int) xPos;
                    updateRange();
                    postInvalidate();
                }

                // 单击右边滑块的右边线条时， 右边滑块滑动到对应的位置
                if (xPos <= lineEnd && xPos >= upperCenterX + bmpWidth / 2) {
                    upperCenterX = (int) xPos;
                    updateRange();
                    postInvalidate();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                // 滑动左边滑块时
                if (isLowerMoving) {
                    if (xPos >= lineStart && xPos < upperCenterX - bmpWidth) {
                        lowerCenterX = (int) xPos;
                        updateRange();
                        postInvalidate();
                    }
                }

                // 滑动右边滑块时
                if (isUpperMoving) {
                    if (xPos > lowerCenterX + bmpWidth && xPos < lineEnd) {
                        upperCenterX = (int) xPos;
                        updateRange();
                        postInvalidate();
                    }
                }

                break;
            case MotionEvent.ACTION_UP:
                // 修改滑块的滑动状态为不再滑动
                isLowerMoving = false;
                isUpperMoving = false;
                break;
            default:
                break;
        }

        return true;
    }

    // 计算指定滑块对应的范围值
    private float computRange(float range) {
        return (range - lineStart) * (bigValue - smallValue) / lineLength + smallValue;
    }

    // 滑动滑块的过程中，更新滑块上方的范围标识
    private void updateRange() {
        smallRange = computRange(lowerCenterX);
        bigRange = computRange(upperCenterX);

        if (null != onRangeChangedListener) {
            onRangeChangedListener.onRangeChanged(smallRange, bigRange);
        }
    }

    // 注册滑块范围值改变事件的监听
    public void setOnRangeChangedListener(
            OnRangeChangedListener onRangeChangedListener) {
        this.onRangeChangedListener = onRangeChangedListener;
    }

    // 公共接口，用户回调接口范围值的改变
    public interface OnRangeChangedListener {
        public void onRangeChanged(float lowerRange, float upperRange);
    }
}
